#pragma once
#include <QString>
#include <QIcon>
#include <QUuid>
#include <QDateTime>
#include <QFile>
#include <QFileInfo>
#include <QDebug>

namespace model
{
//--------------------------------------------------工具函数类--------------------------------------------------

//去掉文件路径，获取文件名
static inline QString getFileName(const QString& path) {
    QFileInfo fileInfo(path);
    return fileInfo.fileName();
}

//打印日志的格式
#define TAG QString("[%1:%2]").arg(model::getFileName(__FILE__), QString::number(__LINE__))
// #define TAG "[" << __LINE__ << "]"

//Qt日志系统,noquote()在输出日志消息时不要添加引号
//qDebug 打印字符串的时候, 就会自动加上 " "
#define LOG() qDebug().noquote() << TAG

// 读写文件操作.
// 从指定文件中, 读取所有的二进制内容. 得到一个 QByteArray
static inline QByteArray loadFileToByteArray(const QString& path) {
    QFile file(path);
    bool ok = file.open(QFile::ReadOnly);
    if (!ok) {
        LOG() << "文件打开失败!";
        return QByteArray();
    }
    QByteArray content = file.readAll();
    file.close();
    return content;
}

// 把 QByteArray 中的内容, 写入到某个指定文件里
static inline void writeByteArrayToFile(const QString& path, const QByteArray& content) {
    QFile file(path);
    bool ok = file.open(QFile::WriteOnly);
    if (!ok) {
        LOG() << "文件打开失败!";
        return;
    }
    file.write(content);
    //文件关闭前先刷新缓冲区
    file.flush();
    file.close();
}

static inline QString formatTime(int64_t timestamp) {
    // 先把时间戳, 转换成 QDateTime 对象
    QDateTime dateTime = QDateTime::fromSecsSinceEpoch(timestamp);
    // 把 QDateTime 对象转成 "格式化时间"
    return dateTime.toString("MM-dd HH:mm:ss");
}

// 得到当前以秒计数的时间
static inline int64_t getTime() {
    return QDateTime::currentSecsSinceEpoch();
}

// 根据 QByteArray, 转成 QIcon
static inline QIcon makeIcon(const QByteArray& byteArray) {
    QPixmap pixmap;//图片处理方法
    pixmap.loadFromData(byteArray);//二进制数据加载图像到 QPixmap
    QIcon icon(pixmap);
    return icon;//图标
}
//--------------------------------------------------用户信息类--------------------------------------------------
class UserInfo//用户信息
{
public:
    QString userId="";     //用户id
    QString nickname="";   //用户昵称
    QString description="";//个性签名
    QString phone="";      //电话号码
    QIcon avatar;          //头像
};
//--------------------------------------------------消息信息类--------------------------------------------------
//消息类型
enum MessageType
{
    TEXT_TYPE,  //   文本
    IMAGE_TYPE, //   图片
    FILE_TYPE,  //   文件
    SPEECH_TYPE,//   语音
    UNKNOWN_TYPE //  未知
};
class Message {
public:
    QString messageId = "";				// 消息的编号
    QString chatSessionId = "";			// 消息所属会话的编号
    QString time = "";					// 消息的时间,通过 "格式化" 时间的方式来表示:如 06-07 12:00:00
    MessageType messageType = TEXT_TYPE;// 消息类型
    UserInfo sender;					// 发送者的信息
    QByteArray content;					// 消息的正文内容
    QString fileId = "";				// 文件的身份标识. 当消息类型为 文件, 图片, 语音 的时候, 才有效. 当消息类型为 文本, 则为 ""
    QString fileName = ""; 				// 文件名称. 只是当消息类型为 文件 消息, 才有效. 其他消息均为 ""

    //  extraInfo 目前只是在消息类型为文件消息时, 作为 "文件名" 补充.
    static Message makeMessage(MessageType messageType, const QString& chatSessionId, const UserInfo& sender,
                               const QByteArray& content, const QString& extraInfo) {
        if (messageType == TEXT_TYPE) {
            return makeTextMessage(chatSessionId, sender, content);
        } else if (messageType == IMAGE_TYPE) {
            return makeImageMessage(chatSessionId, sender, content);
        } else if (messageType == FILE_TYPE) {
            return makeFileMessage(chatSessionId, sender, content, extraInfo);
        } else if (messageType == SPEECH_TYPE) {
            return makeSpeechMessage(chatSessionId, sender, content);
        } else {
            // 触发了未知的消息类型
            return Message();
        }
    }
private:
    // 生成唯一的 messageId,截取从uuid的后12位，开头+M标识
    static QString makeId() {
        return "M" + QUuid::createUuid().toString().sliced(25, 12);
    }

    static Message makeTextMessage(const QString& chatSessionId, const UserInfo& sender, const QByteArray& content) {
        Message message;
        // 此处需要确保, 设置的 messageId 是 "唯一" 的
        message.messageId = makeId();
        message.chatSessionId = chatSessionId;
        message.sender = sender;
        message.time = formatTime(getTime()); // 生成一个格式化时间
        message.content = content;
        message.messageType = TEXT_TYPE;
        // 对于文本消息来说, 下面两个属性不使用, 设为 ""
        message.fileId = "";
        message.fileName = "";
        return message;
    }

    static Message makeImageMessage(const QString& chatSessionId, const UserInfo& sender, const QByteArray& content) {
        Message message;
        message.messageId = makeId();
        message.chatSessionId = chatSessionId;
        message.sender = sender;
        message.time = formatTime(getTime());
        message.content = content;
        message.messageType = IMAGE_TYPE;
        // fileId 后续使用的时候 再设置
        message.fileId = "";
        // fileName 不使用, 直接设为 ""
        message.fileName = "";
        return message;
    }

    static Message makeFileMessage(const QString& chatSessionId, const UserInfo& sender, const QByteArray& content, const QString& fileName) {
        Message message;
        message.messageId = makeId();
        message.chatSessionId = chatSessionId;
        message.sender = sender;
        message.time = formatTime(getTime());
        message.content = content;
        message.messageType = FILE_TYPE;
        // fileId 后续使用的时候设置
        message.fileId = "";
        message.fileName = fileName;
        return message;
    }

    static Message makeSpeechMessage(const QString& chatSessionId, const UserInfo& sender, const QByteArray& content) {
        Message message;
        message.messageId = makeId();
        message.chatSessionId = chatSessionId;
        message.sender = sender;
        message.time = formatTime(getTime());
        message.content = content;
        message.messageType = SPEECH_TYPE;
        // fileId 后续使用的时候设置
        message.fileId = "";
        // fileName 不使用, 直接设为 ""
        message.fileName = "";
        return message;
    }


};

//--------------------------------------------------会话信息类--------------------------------------------------
class chatSessionInfo
{
public:
    QString chatSessionId = "";	  		// 会话编号
    QString chatSessionName = "";		// 会话名字, 单聊, 名字就是对方的昵称; 群聊, 名字就是群聊的名称.
    Message lastMessage;				// 表示最新的消息.
    QIcon avatar;						// 会话头像. 如果会话是单聊, 头像就是对方的头像; 如果是群聊, 头像群聊的头像.
    QString userId = "";				// 对于单聊来说, 表示对方的用户 id, 对于群聊设为 ""
};



}// namespace model end
